%% Author: Administrator
%% Created: 2009-4-10
%% Description: TODO: Add description to ogr
-module(ogr).

%%
%% Include files
%%

%% Opcodes
-define(OPEN,           $o).
-define(OPEN_WITH,      $m).

%% ret codes
-define(VALUE,  $v).
-define(OK,     $o).
-define(FERROR, $E).

%%
%% Exported Functions
%%
-export([load_driver/0, open/2]).

%%
%% API Functions
%%
load_driver() ->
    Dir = ".", %filename:join([filename:dirname(code:which(?MODULE)), "..", "priv"]),
    erl_ddll:load_driver(Dir, "OGR_drv").

-spec open(CellId :: string(), FeatureBin :: binary()) -> any().
open(CellId, FeatureBin) ->
    ImgName = CellId,
    ImgNameBin = list_to_binary(ImgName),
    NameLen = length(ImgName),
    P = open_port({spawn, 'OGR_drv'}, [binary]),
    Res = erlang_port_control(P, ?OPEN_WITH, <<NameLen, ImgNameBin/binary, FeatureBin/binary>>),
    case decode(Res) of
    ok ->
        {ok, {gdal, P}};
    Err ->
        unlink(P),
        exit(P, die),
        Err
    end.

%%
%% Local Functions
%%
erlang_port_control(P, C, Data) ->
    erlang:port_control(P, C, Data).

decode(Res)  ->
    case Res of
    <<?VALUE, Bin/binary>> ->
        {ok, Bin};
    <<?OK>> ->
        ok;
    <<?FERROR, Err/binary>> ->
        {error, list_to_atom(binary_to_list(Err))}
    end.
